package stocklist

import (
	"fmt"
	"strings"

	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"

	"github.com/PuerkitoBio/goquery"

	"gitee.com/Flearning/go_crawl/modules/mgobson"
	"gitee.com/Flearning/go_crawl/utils"
)

type (
	CrawlInfo struct {
		UriPath  string
		DomXpath []string
	}

	//	StockList struct {
	//		Id_ bson.ObjectId `bson:"_id,omitempty" json:"id"`
	//		Stock
	//	}

	Stock struct {
		Id_  bson.ObjectId `bson:"_id,omitempty" json:"id"`
		Name string        `bson:"name" json:"name"`
		Code string        `bson:"code" json:"code"`
		Type string        `bson:"type" json:"type"`
	}
)

func NewCrawlInfo(ci *CrawlInfo) *CrawlInfo {
	return &CrawlInfo{
		ci.UriPath,
		ci.DomXpath,
	}
}

var sts *[]Stock
var sBonsM map[int][]string

func (c *CrawlInfo) Crawl() map[int][]string {
	doc, err := goquery.NewDocument(c.UriPath)
	if err != nil {
		fmt.Println(err)
	}
	var listSt []string
	sBonsM = make(map[int][]string)

	doc.Find(c.DomXpath[0]).Each(func(i int, s *goquery.Selection) {
		textStr := s.Find(c.DomXpath[1]).Text()
		b, e := utils.GbkToUtf8([]byte(textStr))
		if e != nil {
			fmt.Println(e)
		}
		listSt = sepStock(string(b))
		sBonsM[i] = listSt
	})
	return sBonsM
}

func GetBsonData(sbm map[int][]string) []interface{} {
	var td []interface{}
	for k, v := range sbm {
		typ := ""
		if k == 0 {
			typ = "sh"
		} else {
			typ = "sz"
		}
		l := len(v)
		i := 0
		for {
			//fmt.Println(i, v[i], typ)
			tVal := strings.Split(v[i], ",")
			s := &Stock{
				Name: tVal[0],
				Code: tVal[1],
				Type: typ,
			}
			//fmt.Println(i, s)
			i++
			if i == (l - 1) {
				break
			}
			td = append(td, s)
		}
	}
	return td
}

// 数据组合方法
func sepStock(list string) []string {
	var res []string
	lists := strings.Split(list, ")")
	for _, val := range lists {
		tmp := strings.Split(val, "(")
		res = append(res, strings.Join(tmp, ","))
	}
	return res
}

func CrawlData() (int, error) {
	var (
		i   int
		err error
	)
	uri := "http://quote.eastmoney.com/stocklist.html"
	sci := &CrawlInfo{
		UriPath:  uri,
		DomXpath: []string{"#quotesearch ul", "li"},
	}
	c := NewCrawlInfo(sci)
	sdm := c.Crawl()
	res := GetBsonData(sdm)

	i, err = RunCount()
	if i > 0 {
		err = RunRemoveAllDocs()
	}
	err = RunInstert(res...)
	i, err = RunCount()
	return i, err
}

func RunInstert(v ...interface{}) error {
	query := func(c *mgo.Collection) error {
		return c.Insert(v...)
	}
	return mgobson.WatchCollection("stocks_data", query)
}

func RunCount() (int, error) {
	var count int
	var err error
	query := func(c *mgo.Collection) error {
		count, err = c.Count()
		return err
	}
	err = mgobson.WatchCollection("stocks_data", query)
	return count, err
}

func RunRemoveAllDocs() error {
	query := func(c *mgo.Collection) error {
		// _, err := c.RemoveAll(nil)
		return c.DropCollection()
	}
	return mgobson.WatchCollection("stocks_data", query)
}
